﻿/*
 * Author: Mattan360
 * Contributors:
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Irrlicht.Net.Video;

namespace Irrlicht.Net.Scene
{
    public sealed class AnimatedMeshSceneNode : SceneNode
    {
        #region PInvoke
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void AniMesh_SetMD2Animation(IntPtr amsn, uint animation);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern float AniMesh_GetAnimationSpeed(IntPtr amsn);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern int AniMesh_GetEndFrame(IntPtr amsn);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern float AniMesh_GetFrameNr(IntPtr amsn);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern uint AniMesh_GetJointCount(IntPtr amsn);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern IntPtr AniMesh_GetMesh(IntPtr amsn);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern int AniMesh_GetStartFrame(IntPtr amsn);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern bool AniMesh_SetFrameLoop(IntPtr amsn, int begin, int end);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void AniMesh_SetAnimationSpeed(IntPtr amsn, float framesPerSecond);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void AniMesh_SetCurrentFrame(IntPtr amsn, float frame);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void AniMesh_SetMesh(IntPtr amsn, IntPtr mesh);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void AniMesh_SetTransitionTime(IntPtr amsn, float time);    
        #endregion

        public AnimatedMeshSceneNode(IntPtr pointer)
            : base(pointer)
        { }

        internal AnimationTypes animation = AnimationTypes.Count;

        public AnimationTypes Animation
        {
            get
            {
                return animation;
            }

            set
            {
                AnimationTypes ani = value;
                AniMesh_SetMD2Animation(pointer, (uint)ani);
                animation = ani;
            }
        }

        /// <summary>
        /// Gets or sets the animation speed
        /// </summary>
        public float AnimationSpeed
        {
            get
            {
                return AniMesh_GetAnimationSpeed(pointer);
            }

            set
            {
                AniMesh_SetAnimationSpeed(pointer, value);
            }
        }

        public float CurrentFrame
        {
            get
            {
                return AniMesh_GetFrameNr(pointer);
            }
        
            set
            {
                AniMesh_SetCurrentFrame(pointer, value);
            }
        }

        public AnimatedMesh Mesh
        {
            get
            {
                return AnimatedMesh.CreateAnimatedMesh(AniMesh_GetMesh(pointer));
            }
        
            set
            {
                AniMesh_SetMesh(pointer, value.pointer);
            }
        }

        public int EndFrame
        {
            get
            {
                return AniMesh_GetEndFrame(pointer);
            }
        }

        public uint JointCount
        {
            get
            {
                return AniMesh_GetJointCount(pointer);
            }
        }

        public int StartFrame 
        {
            get
            {
                return AniMesh_GetStartFrame(pointer);
            }
        }
        public float TransitionTime
        {
            set
            {
                AniMesh_SetTransitionTime(pointer, value);    
            }
        }
        
        public bool SetFrameLoop(int begin, int end)
        {
            return AniMesh_SetFrameLoop(pointer, begin, end);
        }
    }
}
